Araştırmanın Amacı

Metin madenciliği, insanların ne hakkında konuştuklarını bilmemizin yanı sıra hakkında nasıl konuştuklarını da bilmemizi sağlar. Bu sebeple işletmelerin marka takibi, ürün analizi ve müşteri hizmetleri hakkında iş kararlarını yönlendirmek için büyük miktarda veriye ilişkin iç görü sunma gücüne sahiptir. Bu araştırma projesinin amacı R ile, metnin derinliklerine inmeye ve değerli iç görüler elde etmeye çalışmaktır.

Yelp Verisi Hakkında Genel Bilgiler

Yelp, merkezi San Francisco, Kaliforniya’da bulunan halka açık bir Amerikan şirketidir. Şirket, işletmeler hakkında kitle kaynaklı incelemeler yayınlayan Yelp.com web sitesini ve Yelp mobil uygulamasını geliştirir, işletir ve pazarlar. Ayrıca Yelp Rezervasyonları adı verilen bir çevrimiçi rezervasyon hizmeti de işletmektedir.

Yelp ‘in web sitesi Yelp.com, kitle kaynaklı bir yerel işletme inceleme ve sosyal ağ sitesidir. Site, restoranlar veya okullar gibi özel yerlere ayrılmış sayfalara sahiptir, burada Yelp kullanıcıları bir ila beş yıldız derecelendirme sistemi kullanarak ürün veya hizmetlerin incelemesini yapabilir. İşletmeler ayrıca iletişim bilgilerini, çalışma saatlerini ve diğer temel bilgilerini güncelleyebilir veya özel fırsatlar ekleyebilir. İnceleme yazmaya ek olarak, kullanıcılar incelemelere tepki verebilir, etkinlikler planlayabilir veya kişisel yaşamlarını tartışabilirler.

“Yelp Dataset” adlı veri kümesi ise Yelp ’de bulunan ABD ve Kanada’daki 8 büyükşehir bölgesindeki işletmelerin(Business verisi), incelemelerin(Reviews verisi) ve kullanıcı verilerinin bir alt kümesidir.

Business verisine bir bakış

Business verisi Yelp ’de bulunan işletmelere ait bilgileri içeren veridir.

DT::datatable(as.data.frame(names(business)))
## Rows: 192,609
## Columns: 14
## $ address      <chr> "b'2818 E Camino Acequia Drive'", "b'30 Eglinton Avenu...
## $ name         <chr> "b'Arizona Biltmore Golf Club'", "b'Emerald Chinese Re...
## $ stars        <dbl> 3.0, 2.5, 4.0, 5.0, 4.0, 2.5, 3.5, 3.5, 5.0, 4.5, 2.0,...
## $ longitude    <dbl> -112.01848, -79.65229, -80.85913, -112.39560, -80.8872...
## $ postal_code  <chr> "b'85016'", "b'L5R 3E7'", "b'28210'", "b'85338'", "b'2...
## $ business_id  <chr> "b'1SWheh84yJXfytovILXOAQ'", "b'QXAEGFB4oINsVuTFxEYKFQ...
## $ latitude     <dbl> 33.52214, 43.60550, 35.09256, 33.45561, 35.19001, 43.5...
## $ review_count <dbl> 5, 128, 170, 3, 4, 3, 7, 3, 8, 8, 5, 18, 9, 16, 7, 4, ...
## $ categories   <chr> "b'Golf, Active Life'", "b'Specialty Food, Restaurants...
## $ city         <chr> "b'Phoenix'", "b'Mississauga'", "b'Charlotte'", "b'Goo...
## $ is_open      <dbl> 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, ...
## $ hours        <chr> NA, "{'Monday': '9:0-0:0', 'Tuesday': '9:0-0:0', 'Wedn...
## $ attributes   <chr> "{'GoodForKids': 'False'}", "{'RestaurantsReservations...
## $ state        <chr> "b'AZ'", "b'ON'", "b'NC'", "b'AZ'", "b'NC'", "b'ON'", ...

1) address : adres

2) name : işletmenin adı

3) stars : işletmenin derecelendirmesini sağlar. minimum = 0, maksimum = 5

4) longitude : işletmenin boylam koordinatı. haritadaki konumu çizmek için kullanılacaktır

5) postal_code : posta kodu

6) business_id : işletmenin ID si

7) latitude : işletmenin enlem koordinatı. Haritadaki konumu çizmek için kullanılacaktır

8) review_count : inceleme sayısı

9) categories : işletmenin dahil olduğu kategoriler (golf, aktif yaşam, yemek vs..)

10) city : işletmenin bulunduğu şehir

11) is_open : işletmenin açık/kapalı durumu

12) hours : işletmenin çalışma saatleri

13) attributes : işletmenin sahip olduğu özellikler (‘GoodForKids’: ‘False’ , GoodForMeal vs..)

14) state : durum

Coğrafi Bilgi Sistemi

Business verisinde bulunan boylamlar ve enlemler, tüm işletme konumlarını Coğrafi Bilgi Sistemi ile haritalamak için kullanacağız. Noktaların boyutu, belirli bir alanda incelenen işletmelerin sayısını yansıtır. Nokta ne kadar büyük olursa, bölgedeki işletme sayısı o kadar büyük olur.

PlotOnStaticMap(lat = business$latitude, lon = business$longitude,  zoom =5, size = c(640,640), cex = 1.4, pch = 19, col = "red", FUN = points, add = F)

Reviews verisine bir bakış

Reviews verisi Yelp ’de bulunan işletmelere ait kullanıcı incelemelerini içeren veridir.

DT::datatable(as.data.frame(names(reviews)))
glimpse(reviews)
## Rows: 10,000
## Columns: 10
## $ business_id <chr> "9yKzy9PApeiPPOUJEtnvkg", "ZRJwVLyzEJq1VAihDhYiow", "6o...
## $ date        <date> 2011-01-26, 2011-07-27, 2012-06-14, 2010-05-27, 2012-0...
## $ review_id   <chr> "fWKvX83p0-ka4JS3dc6E5A", "IjZ33sJrzXqU-0X6U8NwyA", "IE...
## $ stars       <dbl> 5, 5, 4, 5, 5, 4, 5, 4, 4, 5, 5, 5, 5, 4, 4, 2, 3, 5, 3...
## $ text        <chr> "My wife took me here on my birthday for breakfast and ...
## $ type        <chr> "review", "review", "review", "review", "review", "revi...
## $ user_id     <chr> "rLtl8ZkDX5vH5nAx9C3q5Q", "0a2KyEL0d3Yb1V6aivbIuQ", "0h...
## $ cool        <dbl> 2, 0, 0, 1, 0, 4, 7, 0, 0, 0, 1, 1, 1, 1, 1, 0, 3, 0, 5...
## $ useful      <dbl> 5, 0, 1, 2, 0, 3, 7, 1, 0, 1, 3, 1, 2, 2, 1, 2, 4, 0, 6...
## $ funny       <dbl> 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 4...

1) business_id : incelenen işletmenin ID si

2) date : inceleme tarihi

3) review_id : incelemenin ID si

4) stars : kullanıcı tarafından işletme için verilen yıldızlar

5) text : inceleme metni

6) type : inceleme tipi

7) user_id : kullanıcı ID si

8) cool : incelemeyi cool bulan kullanıcı sayısı

9) useful : incelemeyş faydalı bulan kullanıcı sayısı

10) funny : incelemeyi komik bulan kullanıcı sayısı

Keşifsel Veri Analizi

İşletme bilgilerinin bulunduğu business verisinden, işletme başına ortalama inceleme sayısına bakalım.

mean(business$review_count)
## [1] 33.53896

Toplam yıldızların dağılımına bakalım.

ggplot(reviews, aes(x=stars))+
  geom_bar(stat="bin", bins= 9, fill="violetred4") + 
  geom_text(stat='count', aes(label=..count..), vjust=1.6, color="white") +
  ggtitle("Yıldızların Dağılım Grafiği") +
  xlab("Yıldızlar") + ylab("Miktar") +
  theme_minimal()

En çok 4 ve 5 yıldızlı incelemelerin olduğunu görüyoruz. Bu sebeple müşterilerin genel olarak yalnızca olumlu olarak çok etkilendilerinde inceleme bırakma eğilimi göstereceklerini düşünebiliriz.

İncelemelerin diline bakalım.

TextCat paketi bir metin sınıflandırma aracıdır ve birincil kullanımı dil tanımlamasıdır. 75 dile kadar algılayabilir.

İlk 20 kullanıcı yorumunun hangi dilde yazıldığını bu paket yardımı ile bulalım.

textcat(reviews[1:20,]$text)
##  [1] "english" "english" "english" "english" "english" "english" "english"
##  [8] "scots"   "english" "english" "english" "english" "english" "english"
## [15] "english" "english" "english" "english" "english" "english"

Yelp ’de en fazla bulunan ilk 10 işletme kategorisine bakalım.

categories = str_split(business$categories,";")
categories = as.data.frame(unlist(categories))
colnames(categories) = c("Name")

categories %>%
  group_by(Name) %>%
  summarise(Count = n()) %>%
  arrange(desc(Count)) %>%
  ungroup() %>%
  mutate(Name = reorder(Name,Count)) %>%
  head(10) %>%
  
  
  ggplot(aes(x = Name,y = Count)) +
  geom_bar(stat='identity',colour="white", fill ="violetred4") +
  geom_text(aes(x = Name, y = 1, label = paste0("(",Count,")",sep="")),
            hjust=0, vjust=.5, size = 4, colour = 'white',
            fontface = 'bold') +
  labs(x = 'Kategori Adı', y = 'Miktar', 
       title = 'En Popüler 10 İşletme Kategorisi') +
  coord_flip() + 
  theme_bw()

Yüksek İnceleme sayılarına sahip en iyi restoranlar. Yüksek inceleme sayıları, buraların popüler/sık ziyaret edilen yerler olduğu anlamına gelir. Ortalama puanlarını görselleştirelim.

b <- business %>% 
     group_by(name) %>% 
     summarize(m=mean(stars),s=sum(review_count)) %>% 
     filter(s > 100) %>%
     arrange(desc(s)) %>% head(10)
  
b %>% ggplot(aes(name,s))+geom_col(aes(fill=m)) + coord_flip() + labs(fill= 'Ortalama Yıldız') + ylab('inceleme sayısı')

En çok yorumlanan restoranın Starbucks olduğunu, ardından Hash house ve Mcdonalds’ın geldiğini görüyoruz.

Yelp ’de bulunan işletmeleri, kullanıcılar tarafından en fazla incelemeye sahip ilk 10 şehire bakalım.

business %>%
  group_by(city) %>%
  summarise(Count = n()) %>%
  arrange(desc(Count)) %>%
  ungroup() %>%
  mutate(City = reorder(city,Count)) %>%
  head(10) %>%
  ggplot(aes(x = City,y = Count)) +
  geom_bar(stat='identity',colour="white", fill ="violetred4") +
  geom_text(aes(x = City, y = 1, label = paste0("(",round(Count/1e3)," K )",sep="")),
            hjust=0, vjust=.5, size = 4, colour = 'white',
            fontface = 'bold') +
  labs(x = 'Şehir', y = 'İnceleme Miktarı', 
       title = 'En Fazla İncelemeye Sahip İlk 10 Şehir') +
  coord_flip() + 
  theme_bw()

Las Vegas en fazla incelemeye sahiptir.

Business verisinde bulunan koordinatlar yardımıyla Las Vegas ’da bulunan işletmelere harita üzerinden bakalım.

LasvegasCoords = business %>% filter(city == "b'Las Vegas'")

center_lon = median(LasvegasCoords$longitude,na.rm = TRUE)
center_lat = median(LasvegasCoords$latitude,na.rm = TRUE)

leaflet(LasvegasCoords) %>% addProviderTiles("Esri.NatGeoWorldMap") %>%
  addCircles(lng = ~longitude, lat = ~latitude,radius = ~sqrt(review_count))  %>%
  
  # controls
  setView(lng=center_lon, lat=center_lat,zoom = 13)

Las Vegas ’da bulunan restoranların sayısına bakalım.

geographical_map <- function(location_name){
  
      location_business <- business %>%
                          # filter for the city
                          filter(city == location_name) %>%
                          # Creates 3 level based on rating
                          mutate( rating_level = ifelse(stars == 4 | stars == 5 ,"High", ifelse(stars == 3, "Medium", "Low")))
      
      # Creates color pallette for rating levels
      pallete <- colorFactor(c("dark red",  "blue","dark green"), domain = c("Low", "Medium","High"))
     
      location_business %>%  
                 leaflet() %>% 
                 setView(lng = mean(location_business$longitude), 
                         lat = mean(location_business$latitude), 
                         zoom = 12) %>% 
                 addProviderTiles(providers$CartoDB.Positron) %>%
                 addCircleMarkers(~longitude, 
                                  ~latitude,
                                  radius = 3,
                                  fillOpacity = 0.5,
                                  # Creates clusters for restaurants on high level
                                  clusterOptions = markerClusterOptions(),
                                  # Color palette is assigned based on rating level
                                  color = ~pallete(rating_level))}

     
geographical_map("b'Las Vegas'")

İşletme yoğunluğu en fazla Las Vegas Strip bölgesindedir.

Wikipedia : Lüks kumarhane otellerinin yer aldığı, neon ışıklarla bezeli Strip, Las Vegas’ı mükemmel özetler. Devasa otellerde kumarhane katlarının yanı sıra pek çok farklı mağaza, her türden restoran ve müzik, komedi ile sirk gösterilerinin düzenlendiği performans alanları vardır.

Wordcloud

Bir şehir için kelime sıklığı analizi yapmak aynı zamanda hangi sosyal aktivitelerin ve ilgi alanlarının şehirde popüler olduğuna dair ipuçları verir. Las Vegas ’da bulunan işletme kategorilerine kelime bulutu ile bakalım.

vegasbusiness <- subset(business, city == "b'Las Vegas'") #las vegas bilgileri
vegasfood <- subset(vegasbusiness, grepl("Food|Restaurants", vegasbusiness$categories))
foodvector <- unlist(strsplit(vegasfood$categories, ";"))


unwanted <- c("Restaurants", "Food", "Shopping", "Specialty", "Grocery", "Convenience Stores", "event", "planning", "services", "new")

sortedfoodvector <- removeWords(foodvector, unwanted)

wordcloud(sortedfoodvector, min.freq = 300, colors=brewer.pal(8, "Dark2"))

Las Vegas yemeklerinin ve sosyal ortamının çoğunlukla barlar, amerikan yemekleri ve gece hayatından oluştuğu gözükmekte. Pizza, sandviç ve hamburger gibi klasikler mekanlarda genel olarak hakim kategoriler. Ayrıca meksika yemekleri ve kahve de hakim gözükmekte.

mon_ami_gabi = business %>% filter(city == "b'Las Vegas'") %>%
  select(name,stars,city,review_count,categories)

datatable((head(mon_ami_gabi)), style="bootstrap", class="table-condensed", options = list(dom = 'tp',scrollX = TRUE))

Sentiment Analizi

review_words <- reviews %>%
  select(review_id, business_id, stars, text) %>%
  unnest_tokens(word, text) %>%
  filter(!word %in% stop_words$word,
         str_detect(word, "^[a-z']+$"))

review_words
## # A tibble: 452,478 x 4
##    review_id              business_id            stars word       
##    <chr>                  <chr>                  <dbl> <chr>      
##  1 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 wife       
##  2 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 birthday   
##  3 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 breakfast  
##  4 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 excellent  
##  5 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 weather    
##  6 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 perfect    
##  7 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 sitting    
##  8 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 overlooking
##  9 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 grounds    
## 10 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 absolute   
## # ... with 452,468 more rows
library(tidytext) # tidy implementation of NLP methods
library(textdata)
## Warning: package 'textdata' was built under R version 4.0.5
AFINN <- get_sentiments("afinn") %>%
  select(word, afinn_score = value)

AFINN
## # A tibble: 2,477 x 2
##    word       afinn_score
##    <chr>            <dbl>
##  1 abandon             -2
##  2 abandoned           -2
##  3 abandons            -2
##  4 abducted            -2
##  5 abduction           -2
##  6 abductions          -2
##  7 abhor               -3
##  8 abhorred            -3
##  9 abhorrent           -3
## 10 abhors              -3
## # ... with 2,467 more rows
reviews_sentiment <- review_words %>%
  inner_join(AFINN, by = "word") %>%
  group_by(review_id, stars) %>%
  summarize(sentiment = mean(afinn_score))
## `summarise()` regrouping output by 'review_id' (override with `.groups` argument)
reviews_sentiment
## # A tibble: 9,470 x 3
## # Groups:   review_id [9,470]
##    review_id              stars sentiment
##    <chr>                  <dbl>     <dbl>
##  1 --8hpKO4bkweLyEucdxI_w     4      2   
##  2 --DazeDpOApabZnIOIPSrQ     5      0   
##  3 --QCUEmDBlipC_CEutGVFA     4      2   
##  4 --TqfVGywiYWh7Sn9ksBmA     4     -2   
##  5 -_E6jvslAhQHbjNJIKeFQA     5      2   
##  6 -_hed9F2kUDdb4oa1CXKIA     5      2.5 
##  7 -_MguNFy09v8GeFS5NDIbA     5     -0.25
##  8 -04V-J248jjwibqilfLePA     4      2.4 
##  9 -0d1TTyKmgknAYVEDLaqgQ     5      1.31
## 10 -0fImqvIf7zAVacU1BOg8g     5      3   
## # ... with 9,460 more rows
library(ggplot2)
theme_set(theme_bw())

ggplot(reviews_sentiment, aes(stars, sentiment, group = stars)) +
  geom_boxplot() +
  ylab("Average sentiment score")

library(tidytext)

review_words <- reviews %>%
  select(review_id, business_id, stars, text) %>%
  unnest_tokens(word, text) %>%
  filter(!word %in% stop_words$word,
         str_detect(word, "^[a-z']+$"))

review_words
## # A tibble: 452,478 x 4
##    review_id              business_id            stars word       
##    <chr>                  <chr>                  <dbl> <chr>      
##  1 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 wife       
##  2 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 birthday   
##  3 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 breakfast  
##  4 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 excellent  
##  5 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 weather    
##  6 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 perfect    
##  7 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 sitting    
##  8 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 overlooking
##  9 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 grounds    
## 10 fWKvX83p0-ka4JS3dc6E5A 9yKzy9PApeiPPOUJEtnvkg     5 absolute   
## # ... with 452,468 more rows
library(tidytext) # tidy implementation of NLP methods
library(textdata)


AFINN <- get_sentiments("afinn") %>%
  select(word, afinn_score = value)

AFINN
## # A tibble: 2,477 x 2
##    word       afinn_score
##    <chr>            <dbl>
##  1 abandon             -2
##  2 abandoned           -2
##  3 abandons            -2
##  4 abducted            -2
##  5 abduction           -2
##  6 abductions          -2
##  7 abhor               -3
##  8 abhorred            -3
##  9 abhorrent           -3
## 10 abhors              -3
## # ... with 2,467 more rows
reviews_sentiment <- review_words %>%
  inner_join(AFINN, by = "word") %>%
  group_by(review_id, stars) %>%
  summarize(sentiment = mean(afinn_score))
## `summarise()` regrouping output by 'review_id' (override with `.groups` argument)
reviews_sentiment
## # A tibble: 9,470 x 3
## # Groups:   review_id [9,470]
##    review_id              stars sentiment
##    <chr>                  <dbl>     <dbl>
##  1 --8hpKO4bkweLyEucdxI_w     4      2   
##  2 --DazeDpOApabZnIOIPSrQ     5      0   
##  3 --QCUEmDBlipC_CEutGVFA     4      2   
##  4 --TqfVGywiYWh7Sn9ksBmA     4     -2   
##  5 -_E6jvslAhQHbjNJIKeFQA     5      2   
##  6 -_hed9F2kUDdb4oa1CXKIA     5      2.5 
##  7 -_MguNFy09v8GeFS5NDIbA     5     -0.25
##  8 -04V-J248jjwibqilfLePA     4      2.4 
##  9 -0d1TTyKmgknAYVEDLaqgQ     5      1.31
## 10 -0fImqvIf7zAVacU1BOg8g     5      3   
## # ... with 9,460 more rows
library(ggplot2)
theme_set(theme_bw())

ggplot(reviews_sentiment, aes(stars, sentiment, group = stars)) +
  geom_boxplot() +
  ylab("Average sentiment score")

Kutu grafiği, ortalama derecelendirmeler ve duyarlılık puanları arasındaki ilişkiyi gösterir.

review_words_counted <- review_words %>%
  count(review_id, business_id, stars, word) %>%
  ungroup()

review_words_counted
## # A tibble: 388,427 x 5
##    review_id              business_id            stars word          n
##    <chr>                  <chr>                  <dbl> <chr>     <int>
##  1 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 alley         1
##  2 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 band          1
##  3 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 bar           1
##  4 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 beer          2
##  5 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 brew          1
##  6 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 cocktails     1
##  7 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 cover         1
##  8 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 easy          1
##  9 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 enjoy         1
## 10 --8hpKO4bkweLyEucdxI_w OdD1GuGNQ64ssJmMJ_D9RQ     4 entrance      1
## # ... with 388,417 more rows
word_summaries <- review_words_counted %>%
  group_by(word) %>%
  summarize(businesses = n_distinct(business_id),
            reviews = n(),
            uses = sum(n),
            average_stars = mean(stars)) %>%
  ungroup()
## `summarise()` ungrouping output (override with `.groups` argument)
word_summaries
## # A tibble: 28,567 x 5
##    word         businesses reviews  uses average_stars
##    <chr>             <int>   <int> <int>         <dbl>
##  1 aa                    5       5    11           4  
##  2 aaa                   2       2     2           4  
##  3 aaaaaalright          1       1     1           3  
##  4 aaand                 1       1     1           4  
##  5 aah                   1       1     1           4  
##  6 aand                  1       1     1           4  
##  7 aaron                 8       8     9           4  
##  8 aaron's               1       1     1           4  
##  9 aarp                  1       1     1           4  
## 10 ab                    4       5     9           4.2
## # ... with 28,557 more rows
word_summaries_filtered <- word_summaries %>%
  filter(reviews >= 200, businesses >= 10)

word_summaries_filtered
## # A tibble: 347 x 5
##    word       businesses reviews  uses average_stars
##    <chr>           <int>   <int> <int>         <dbl>
##  1 absolutely        271     298   318          3.92
##  2 add               260     272   290          3.69
##  3 ago               297     315   334          3.65
##  4 amazing           616     838   976          4.37
##  5 ambiance          191     236   249          3.89
##  6 amount            249     261   282          3.70
##  7 appetizer         213     271   310          3.77
##  8 arizona           248     276   304          3.96
##  9 arrived           220     245   287          3.36
## 10 ate               275     302   333          3.49
## # ... with 337 more rows
word_summaries_filtered %>%
  arrange(desc(average_stars))
## # A tibble: 347 x 5
##    word      businesses reviews  uses average_stars
##    <chr>          <int>   <int> <int>         <dbl>
##  1 highly           288     310   328          4.39
##  2 fantastic        350     430   474          4.38
##  3 perfect          439     552   649          4.37
##  4 amazing          616     838   976          4.37
##  5 wonderful        362     419   472          4.32
##  6 favorite         621     782   880          4.29
##  7 awesome          594     731   825          4.25
##  8 excellent        508     625   724          4.24
##  9 delicious        757    1133  1314          4.23
## 10 beautiful        229     263   288          4.20
## # ... with 337 more rows
word_summaries_filtered %>%
  arrange(average_stars)
## # A tibble: 347 x 5
##    word      businesses reviews  uses average_stars
##    <chr>          <int>   <int> <int>         <dbl>
##  1 manager          205     219   285          2.84
##  2 money            316     335   376          2.94
##  3 waited           186     209   250          2.97
##  4 customers        211     218   251          2.98
##  5 told             423     471   615          2.99
##  6 waitress         280     338   426          3.08
##  7 slow             204     230   248          3.09
##  8 minutes          513     591   796          3.10
##  9 dry              230     255   284          3.10
## 10 guess            305     324   354          3.13
## # ... with 337 more rows
ggplot(word_summaries_filtered, aes(reviews, average_stars)) +
  geom_point() +
  geom_text(aes(label = word), check_overlap = TRUE, vjust = 1, hjust = 1) +
  scale_x_log10() +
  geom_hline(yintercept = mean(reviews$stars), color = "red", lty = 2) +
  xlab("# of reviews") +
  ylab("Average Stars")